#include "SceneManager.h"

SceneManager::SceneManager(void)
{
	m_ColorIndex = 0;
}

SceneManager::~SceneManager(void)
{
	for (int i = 0; i < m_NumObject; i++)
	{
		SAFE_DEL(m_Object[i]);
	}
	SAFE_DEL(m_Object);
	SAFE_DEL(camera);
}

SceneManager* SceneManager::s_Instance = 0;
SceneManager* SceneManager::GetInstance()
{
	if (!s_Instance)
	{
		s_Instance = new SceneManager();
	}
	return s_Instance;
}

Object* SceneManager::GetObject(char* ID)
{
	for (int i = 0; i < m_NumObject; i++)
		if (strcmp(ID, m_Object[i]->GetID()) == 0) 
			return m_Object[i];
	return 0;
}

Object* SceneManager::GetObject(Vector4 color)
{
	for (int i = 0; i < m_NumObject; i++)
	{
		Vector4 tempColor = m_Object[i]->GetColor();
		if (tempColor.x == color.x && tempColor.y == color.y && tempColor.z == color.z && tempColor.w == color.w) 
			return m_Object[i];
	}
	return 0;
}


void SceneManager::Init(char* file)
{
	ResourceManager * RM = ResourceManager::GetInstance();
	FILE * pFile;
	char modelID[10], textureID[10], shaderID[10], ID[10];
	Vector3 tempPos;
	Vector3 tempRot;
	float scale;
	float xPos, yPos, zPos;
	float xRot, yRot, zRot;
	float nearPlane, farPlane, FOV, speed;
	int numTexture;
	Texture** tex;
	
	camera = new Camera();
	light = new Light();
	pFile = fopen(file, "r");
	fscanf(pFile, "#NrObject: %d\n",&m_NumObject);
	m_Object = new Object*[m_NumObject];
	for (int i = 0; i < m_NumObject; i++)
	{

		fscanf(pFile, "ID: %s Model: %s Texture: %d", ID, modelID, &numTexture);
		tex = new Texture*[numTexture];
		for (int j = 0; j < numTexture; j++)
		{
			fscanf(pFile, " %s", textureID);
			tex[j] = new Texture;
			tex[j] = RM->GetTexture(textureID);
		}
		fscanf(pFile," Shader: %s Position: %f, %f, %f Rotation: %f, %f, %f Scale: %f\n", shaderID, &xPos, &yPos, &zPos, &xRot, &yRot, &zRot, &scale);
		m_Object[i] = new Object;
		m_Object[i]->Init(ID,Vector3(xPos, yPos, zPos), Vector3(xRot, yRot, zRot), scale, Vector4(++m_ColorIndex, 0, 0, 255), numTexture, tex, RM->GetModel(modelID), RM->GetShader(shaderID), camera);
	}
	fscanf(pFile, "#Camera:\n");
	fscanf(pFile, "Near: %f Far: %f FOV: %f Speed: %f\n", &nearPlane, &farPlane, &FOV, &speed);
	camera->Init(nearPlane, farPlane, FOV, (float)SCREEN_W/ SCREEN_H, speed);
	light->Init(GetObject("Light"));
	delete[] file;

}

void SceneManager::Draw(int fboId, bool isFill, Shader* lightCastShader)
{
	if (fboId != 0)		
		// set rendering destination to FBO
		glBindFramebuffer(GL_FRAMEBUFFER, fboId);

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	//skyDom.m_Position = cam.position;
	//skyDom.Draw();
	//obj1.Draw();
	//obj2.Draw();
	for (int i = 0; i < m_NumObject; i++)
	{
		Matrix trans;
		Matrix rot;
		Matrix scale;
		trans.SetTranslation(m_Object[i]->m_Position.x, m_Object[i]->m_Position.y, m_Object[i]->m_Position.z);
		rot.SetRotation(m_Object[i]->m_Rotation.x, m_Object[i]->m_Rotation.y, m_Object[i]->m_Rotation.z);
		scale.SetScale(m_Object[i]->m_Scale);

		Matrix worldMatrix = scale * rot * trans;

		m_Object[i]->Draw(worldMatrix, isFill, lightCastShader);

	}

	//glDisable(GL_DEPTH_TEST);
	//glDisable(GL_CULL_FACE);
	//glDisable(GL_BLEND);

	if (fboId != 0)		
		// set rendering destination to FBO
		glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

void SceneManager::Update()
{
	camera->Update();
}